﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SeniorEvent
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        public delegate string testEventHander(string arg);



        private void btnAction_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = "";
            //Action委托,Func 委托 作为方法的类型，
            //Test(msg, "huanggang");
            //Test(msg, 30);

            TestFunc(msgFunc, "shifang");
            TestFunc(msgFunc, 31);


            //delegate 委托
            //将方法msgDelegate 与委托绑定，
            //testEventHander testEvent = new testEventHander(msgDelegate);
            //MessageBox.Show( msgDelegate("huanggang"));

        }
        /// <summary>
        ///   Action是无返回值的泛型委托 例如Action<int,string> 表示有传入参数int,string无返回值的委托
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action"></param>
        /// <param name="p"></param>
        public void Test<T>(Action<T> action, T p)
        {
            //action(p);

            // action.Invoke(p); //同步调用
            action.BeginInvoke(p, null, null); //异步调用
            this.richTextBox1.Text += "Test" + "\r\n";

        }
        /// <summary>
        ///  Func是有返回值的泛型委托
        /// T1为传入参数，T2为函数返回类型 比如Func(string,int) 表示传入参数是string类型，函数返回类型为int
        /// BeginInvoke  方法参数不定，但是最后两个参数固定，其中倒数第2个参数，到时第1个参数为必须，若没有，传入null,
        /// 倒数第2个参数表示回调函数，倒数第1个参数表示传给回调函数的参数内容
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="func"></param>
        /// <param name="arg"></param>
        public void TestFunc<T1, T2>(Func<T1, T2> func, T1 arg)
        {

            //  this.richTextBox1.Text += func(arg);

            //  this.richTextBox1.Text += func.Invoke(arg);//同步

            IAsyncResult asyncResult = func.BeginInvoke(arg, null, null);//异步调用，

            var result = func.EndInvoke(asyncResult); //接收委托返回的值
            this.richTextBox1.Text += result;
        }

        public void msg(string name)
        {
            // 当使用   action.BeginInvoke(p,null,null) 调用时，会报错，提示从不是当前的线程访问

            // this.richTextBox1.Text += name+"\r\n";

            //action.BeginInvoke(p,null,null) 调用 ,使用线程匿名委托 delegate (){} 匿名委托写法

            richTextBox1.BeginInvoke(new ThreadStart(delegate ()
            {
                richTextBox1.Text += name + "\r\n";
            }));

        }
        public void msg(int age)
        {
            richTextBox1.BeginInvoke(new ThreadStart(delegate ()
            {
                richTextBox1.Text += age + "\r\n";
            }));

        }
        public string msgFunc(string name)
        {
            //this.richTextBox1.Text += name + "\r\n";
            return name + "\r\n";
        }
        public int msgFunc(int age)
        {
            return age;
        }

        public string msgDelegate(string name)
        {
            //this.richTextBox1.Text += name + "\r\n";
            return name + "\r\n";
        }
        public int msgDelegate(int age)
        {
            return age;
        }

        private void btnAsync_Click(object sender, EventArgs e)
        {
            Action<string> ac = msg;
            ac("huanggang");

            //匿名函数的写法，Lambda写法 ，可以理解为委托类型的对象
            Action<string> ac1 = (t) => { msg(t); };

            Action<int> ac2 = (a) => { msg(a); };
            ac1.Invoke("石芳");
            ac2.Invoke(30);
            testEventHander testEvent = msgDelegate;
            testEvent("30");
        }
    }
}
